import { loginAPI, getUserInfoAPI, getUserDetailByIdAPI } from '@/api/user'
import { getToken, setToken, removeToken, setTimeStamp } from '@/utils/auth'
import { resetRouter } from '@/router'
const state = {
  token: getToken(),
  userInfo: {} // 不能用null，因为null.name会报错
}

// 数据持久化 - 初始化的时候先从缓存里读取，数据变化时，同步给缓存
const mutations = {
  // token相关
  setToken(state, token) {
    state.token = token
    setToken(token)
  },
  removeToken(state) {
    state.token = null
    removeToken()
  },
  // 用户信息相关
  setUserInfo(state, result) {
    state.userInfo = result // 或者 state.userInfo = {...result}   只有浅拷贝才能是响应式的
  },
  removeUserInfo(state) {
    state.userInfo = {}
  }
}

const actions = {
// actions中写异步操作 - 发请求

  // 登录
  async login(context, data) {
    const result = await loginAPI(data)
    // 由于在响应拦截器中进行了判断，这儿不用再判断，只有success返回true才会进入这儿，并且再相应拦截器中进行了处理，如果请求成功，直接让相应拦截器返回解构赋值后的data，这儿也不用再result.data.data，直接用result就可以
    /* if (result.data.success) {
      context.commit('setToken', result.data.data)
    } */
    context.commit('setToken', result)
    setTimeStamp()
  },
  // 获取用户信息
  async getUserInfo(context) { // 什么时候调用这个方法呢？ - 有了token去获取用户资料的时候 - 路由跳转的时候 - 路由守卫中
    const result = await getUserInfoAPI() // 这儿的result已经是相应拦截器解构赋值过的data对象了
    const detail = await getUserDetailByIdAPI(result.userId)
    const allInfo = { ...result, ...detail }
    context.commit('setUserInfo', allInfo)
    return allInfo // 解决后面的权限问题
  },

  // 登出 - 因为登录操作得到的token、userInfo都存储在vuex中，mutations中有移除token和user Info的操作，所以直接在actions中写登出方法，点击登出调用该方法
  logout(context) {
    context.commit('removeToken')
    context.commit('removeUserInfo')
    // 登出时,重置路由 - 由于我们设置了动态路由 - 用户登录时会根据用户信息配置相应权限,开放对应路由 - 如果登出时不重置路由,让路由恢复到只有静态路由的状态下,那么下一个人登录时会在原路由的基础上不断累加,导致动态路由重复增加且虽然看不到菜单了,但由于路由存在,用户可通过地址栏直接访问路由
    resetRouter()
    // 重置路由后 - vuex中的数据还在 - 要清空permission下的state
    // 在vuex的子模块中调用另一个子模块的方法
    // 如果没有开启命名空间,所有方法都挂载在store上,可以直接访问呢
    // 如果开启了命名空间，需要加上第三个参数{root:true},表示当前context不是子模块了而是父模块
    context.commit('permission/setRoutes', [], { root: true })
  }
  // 或者
  /* login(context, data) {
    return new Promise(function (resolve) {
      loginAPI(data).then(result => {
        if (result.data.success) {
          context.commit('setToken', result.data.data)
          resolve()
        }
      })
    })
  } */
}

const user = {
  namespaced: true,
  state,
  mutations,
  actions
}

export default user
